﻿using Abp.Linq.Expressions;
using Common.Enums;
using Entity.Enums;
using Entity.Models.dto;
using Entity.Models.Entities;
using Entity.Models.vo;
using IBLL;
using IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using utils.enums;
using utils.Enums;
using utils.EX;
using Utils;

namespace BLL
{
    /// <summary>
    /// 工作流实例BLL层
    /// </summary>
    public class WorkFlow_InstanceBLL : IWorkFlow_InstanceBLL
    {
        /// <summary>
        /// 工作流实例DAL接口
        /// </summary>
        IWorkFlow_InstanceDAL _workFlow_InstanceDal;

        /// <summary>
        /// 用户接口
        /// </summary>
        IUserDAL _userDAL;

        //耗材信息接口
        IConsumableInfoDAL _consumableInfoDAL;

        //工作流模板DAL
        IWorkFlow_ModelDAL _workFlow_ModelDAL;

        /// <summary>
        /// 数据库上下文
        /// </summary>
        RepositorySysContext _dbsysContext;

        //部门接口
        IDepartmentDAL _departmenDAL;

        //工作流步骤AL
        IWorkFlow_InstanceStepDAL _workFlow_InstanceStepDAL;

        //构造注入
        public WorkFlow_InstanceBLL(IWorkFlow_InstanceDAL workFlow_Instance, IUserDAL userDAL,
            IConsumableInfoDAL consumableInfoDAL, IWorkFlow_ModelDAL workFlow_ModelDAL,
            RepositorySysContext dbsysContext, IDepartmentDAL departmenDAL,
            IWorkFlow_InstanceStepDAL WorkFlow_InstanceStepDAL)
        {
            _workFlow_InstanceDal = workFlow_Instance;
            _userDAL = userDAL;
            _consumableInfoDAL = consumableInfoDAL;
            _workFlow_ModelDAL = workFlow_ModelDAL;
            _dbsysContext = dbsysContext;
            _departmenDAL = departmenDAL;
            _workFlow_InstanceStepDAL = WorkFlow_InstanceStepDAL;
        }

        /// <summary>
        /// 工作流实例数据列表、搜索
        /// </summary>
        /// <param name="workFlow_InstanceName">工作流实例名称</param>
        /// <param name="page">页数</param>
        /// <param name="limit">数据条数</param>
        /// <returns></returns>
        public List<WorkFlow_InstanceDTO> getworkFlow_InstanceList(string workFlow_InstanceName, string page, string limit, out int cont)
        {
            //连表
            var datas = from d in _workFlow_InstanceDal.getEntitys()
                        join u in _userDAL.getUserShowDAL().Where(i => i.IsDelete != true)//用户
                        on d.Creator equals u.Id
                        into Temedu
                        from uu in Temedu.DefaultIfEmpty()

                        join d2 in _consumableInfoDAL.getEntitys().Where(u => u.IsDelete != true) //耗材
                        on d.OutGoodsId equals d2.Id
                        into TempDD
                        from dd2 in TempDD.DefaultIfEmpty()

                        join w in _workFlow_ModelDAL.getEntitys().Where(u => u.IsDelete != true)//工作流模板
                        on d.ModelId equals w.Id
                        into Tempwm
                        from WM in Tempwm.DefaultIfEmpty()
                        select new WorkFlow_InstanceDTO
                        {
                            Id = d.Id,
                            _modelName = WM.Title,
                            _status = Enums.getDescribe(d.Status),
                            _reason = d.Reason,
                            _creatorName = uu.UserName,
                            _outNum = d.OutNum,
                            _outGoodsName = dd2.ConsumableName,
                            _createTime = d.CreateTime,
                            _description = d.Description,
                        };

            if (!string.IsNullOrEmpty(workFlow_InstanceName))
            {
                datas = datas.Where(i => i._modelName.Contains(workFlow_InstanceName));
            }
            //分页
            var pagedepartment = datas.OrderByDescending(d => d._createTime).Skip((int.Parse(page) - 1) * int.Parse(limit)).Take(int.Parse(limit)).ToList();
            cont = datas.Count();

            //整合数据
            List<WorkFlow_InstanceDTO> departmentList = new List<WorkFlow_InstanceDTO>();
            foreach (var item in pagedepartment)
            {
                departmentList.Add(new WorkFlow_InstanceDTO(item));
            }

            return departmentList;
        }

        /// <summary>
        /// 添加工作流实例
        /// </summary>
        /// <param name="workFlow_Instance"></param>
        /// <returns></returns>。
        public bool AddWorkFlow_Instance(WorkFlow_Instance workFlow_Instance)
        {
            //打开事务
            using (var Transaction = _dbsysContext.Database.BeginTransaction())
            {
                workFlow_Instance.Status = WorkFlow_InstanceEnums.WorkFlow_InstanceEnumStatus.EXAMINATION;


                //保存工作流实例
                if (_workFlow_InstanceDal.AddEntity(workFlow_Instance) < 1)
                {
                    Transaction.Rollback();//回滚
                    throw new MyException(((int)UserEnums.USER_STATE.LOSE), Enums.getDescribe(UserEnums.USER_STATE.LOSE));
                }

                //获取申请人的部门
                string departmentId = _userDAL.getUserShowDAL().Where(u => u.IsDelete != true && u.Id.EndsWith(workFlow_Instance.Creator)).Select(u => u.DepartmentId).FirstOrDefault();

                //获取申请人部门下的主管ID
                string leaderId = _departmenDAL.getEntitys().Where(d => d.Id.EndsWith(departmentId) && d.IsDelete != true).Select(d => d.LeaderId).FirstOrDefault();
                if (string.IsNullOrEmpty(departmentId))
                {
                    Transaction.Rollback();//回滚
                    throw new MyException(904, "你的未绑定部门，请绑定后再来申请");
                }
                else if (string.IsNullOrEmpty(leaderId))
                {
                    Transaction.Rollback();//回滚
                    throw new MyException(909, "你的部门下主管为空，请完善后再申请");
                }


                //保存工作流步骤
                if (_workFlow_InstanceStepDAL.AddEntity(new WorkFlow_InstanceStep(workFlow_Instance, leaderId)) < 1)
                {
                    Transaction.Rollback();//回滚
                    throw new MyException(((int)UserEnums.USER_STATE.LOSE), Enums.getDescribe(UserEnums.USER_STATE.LOSE));
                }

                //提交事务
                Transaction.Commit();
            }
            return true;
        }

        /// <summary>
        /// 作废
        /// </summary>
        /// <param name="workFlow_InstanceId">作废</param>
        /// <returns></returns>
        public bool DalateWorkFlow_Instance(string workFlow_InstanceId)
        {
            //打开事务
            using (var Transaction = _dbsysContext.Database.BeginTransaction())
            {
                //修改当前实例状态
                WorkFlow_Instance workFlow_Instance= _workFlow_InstanceDal.getEntitys().FirstOrDefault(w => w.Id.EndsWith(workFlow_InstanceId));
                if (workFlow_Instance==null)
                {
                    Transaction.Rollback();
                    throw new MyException(800,"找不到当前实例");
                }
                workFlow_Instance.Status = WorkFlow_InstanceEnums.WorkFlow_InstanceEnumStatus.INVALID;
                if (_workFlow_InstanceDal.UpdataEntity(workFlow_Instance)<1)
                {
                    Transaction.Rollback();
                    throw new MyException(802, "修改实例状态失败");
                }

                //修改步骤状态
                WorkFlow_InstanceStep workFlow_InstanceStep = _workFlow_InstanceStepDAL.getEntitys().OrderByDescending(w => w.CreateTime).FirstOrDefault(w=>w.InstanceId.EndsWith(workFlow_Instance.Id));
                if (workFlow_InstanceStep==null)
                {
                    Transaction.Rollback();
                    throw new MyException(805, "找不到当前步骤");
                }
                //修改
                workFlow_InstanceStep.ReviewStatus = WorkFlow_InstanceEnums.WorkFlow_InstanceStepEnums.INVALID;
                workFlow_InstanceStep.ReviewTime = DateTime.Now;
                if (_workFlow_InstanceStepDAL.UpdataEntity(workFlow_InstanceStep) <1)
                {
                    Transaction.Rollback();
                    throw new MyException(805, "修改步骤状态失败");
                }
                Transaction.Commit();
            }
            return true;
        }



    }
}
